package com.ltmall.api.util;

import com.ltmall.api.comm.Path;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class ImgUtil {

    /**
     * Gets the file types.
     *
     * @return the file types
     */
    public static List<String> getFileTypes() {
        List<String> fileTypes = new ArrayList<String>();
        fileTypes.add("jpg");
        fileTypes.add("png");
        fileTypes.add("jpeg");
        fileTypes.add("bmp");
        fileTypes.add("gif");
        return fileTypes;

    }

    /**
     * Gets the file.
     *
     * @param imgFile     the img file
     * @param projectName the project name
     * @param dir         the dir
     * @return the file
     */
    public static String getFile(MultipartFile imgFile, String projectName,
                                 String dir) {
        // 这是利用UUID产生的32位的名称
        String generateFileName = UUIDGenerator.getUUID32();
        String fileName = imgFile.getOriginalFilename();
        // 获取上传文件类型的扩展名,先得到.的位置，再截取从.的下一个位置到文件的最后，最后得到扩展名
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
        File file = null;
        // 如果扩展名属于允许上传的类型，则创建文件
        if (getFileTypes().contains(ext)) {
            file = creatFolder(projectName, dir, generateFileName + "." + ext);
            try {
                // 保存上传的文件
                imgFile.transferTo(file);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                //出现异常就返回空
                return null;
            }
        } else {
            return null;
        }
        return generateFileName + "." + ext;
    }


    /*
     * 检测与创建一级、二级文件夹、文件名 这里我通过传入的两个字符串来做一级文件夹和二级文件夹名称
     * 通过此种办法我们可以做到根据用户的选择保存到相应的文件夹下
     */

    /**
     * Creat folder.
     *
     * @param projectName the project name
     * @param dir         the dir
     * @param fileName    the file name
     * @return the file
     */
    public static File creatFolder(String projectName, String dir,
                                   String fileName) {
        File file = null;
        projectName = projectName.replaceAll("/", ""); // 去掉"/"
        projectName = projectName.replaceAll(" ", ""); // 替换半角空格
        projectName = projectName.replaceAll(" ", ""); // 替换全角空格

//		dir = dir.replaceAll("/", ""); // 去掉"/"
//		dir = dir.replaceAll(" ", ""); // 替换半角空格
//		dir = dir.replaceAll(" ", ""); // 替换全角空格

        File firstFolder = new File(Path.disk + projectName + "/upload"); //全部放到upload下
        if (!firstFolder.exists()) {
            // 一级目录不存在则创建
            firstFolder.mkdir();
        }
        File secondFolder = new File(firstFolder, dir);
        if (!secondFolder.exists()) {
            secondFolder.mkdirs();
        }
        file = new File(secondFolder, fileName);

//		File firstFolder = new File(Path.disk + projectName); // 一级文件夹
//		if (firstFolder.exists()) { // 如果一级文件夹存在，则检测二级文件夹
//			File secondFolder = new File(firstFolder, dir);
//			if (secondFolder.exists()) { // 如果二级文件夹也存在，则创建文件
//				file = new File(secondFolder, fileName);
//			} else { // 如果二级文件夹不存在，则创建二级文件夹
//				secondFolder.mkdirs();
//				file = new File(secondFolder, fileName); // 创建完二级文件夹后，再合建文件
//			}
//		} else { // 如果一级不存在，则创建一级文件夹
//			firstFolder.mkdir();
//			File secondFolder = new File(firstFolder, dir);
//			if (secondFolder.exists()) { // 如果二级文件夹也存在，则创建文件
//				file = new File(secondFolder, fileName);
//			} else { // 如果二级文件夹不存在，则创建二级文件夹
//				secondFolder.mkdirs();
//				file = new File(secondFolder, fileName);
//			}
//		}
        return file;
    }

    /**
     * Return picture.
     *
     * @param response the response
     * @param picName  the pic name
     * @param picPath  the pic path
     */
    // 图片返回
    public static void returnPicture(HttpServletResponse response, String picName, String picPath) {
        try {
            File dir = new File(picPath);
            File[] files = dir.listFiles();
            // String imgName = imageName;
            int tag = 0;
            for (File file : files) {
                if (file.getName().equals(picName)) {
                    tag = 1;
                    File imgFile = new File(picPath, picName);
                    FileInputStream fis = new FileInputStream(imgFile);
                    int size = fis.available(); // 得到文件大小
                    byte data[] = new byte[size];
                    fis.read(data); // 读数据
                    fis.close();
                    response.setContentType("image/jpg"); // 设置返回的文件类型
                    OutputStream os = response.getOutputStream();
                    os.write(data);
                    os.flush();
                    os.close();
                }
            }
            if (tag == 0) {
                RemoteUtil.response(response, "", 0, "图片不存在");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    //张图，


    /**
     * Save picture.
     *
     * @param picture the picture
     * @param path    the path
     * @return the string
     * @throws Exception the exception
     */
    // 图片存储
    public static String savePicture(String picture, String path)
            throws Exception {
        String uuid = UUIDGenerator.getUUID32();
        if (picture != null) {
            byte[] b = null;
            try {
                b = Base64Coder.decodeLines(picture);
                String fileName = uuid + ".jpg";
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(file.getPath()
                        + "/" + fileName);
                System.out.println(file.getPath());
                fos.write(b);
                fos.flush();
                fos.close();
                return fileName;
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        return null;
    }


    /**
     * 保存图片
     *
     * @param request   the request
     * @param imageName 图片名称
     * @return 图片名称
     */
    public static String saveImgFile(HttpServletRequest request, String imageName, String path) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile imgFile = multipartRequest.getFile(imageName);
        String imgName = multipartRequest.getParameter(imageName);
        if (imgFile == null && imgName != null && imgName.startsWith("http")) {
            int index = imgName.lastIndexOf(File.separator);
            return imgName.substring(index + 1);
        }

        if (imgFile != null) {
            String generaterName = null;
            String fileName = imgFile.getOriginalFilename();
            if (fileName != null && !fileName.equals("")) {
                String project = Path.project;
                // 图片存储
                generaterName = getFile(imgFile, project, path);
            }

            return generaterName;
        }

        return null;
    }

    /**
     * 压缩图片，在源目录生成一个ori备份文件
     *
     * @param path     图片路径
     * @param quantity 压缩质量
     * @return
     */
    public static boolean compressImage(String path, double quantity) {
        String ext = path.substring(path.lastIndexOf(".") + 1, path.length()).toLowerCase();
        if (ext.equals("jpg") || ext.equals("jpeg")) {
            ImageWriter imageWriter = null;
            ImageOutputStream imageOutputStream = null;
            FileOutputStream outputStream = null;
            BufferedImage image = null;
            try {
                String extOri = "ori." + ext;
                File oldFile = new File(path);
                File oriFile = new File(path.replace(ext, extOri));
                oldFile.renameTo(oriFile);
                if (!oriFile.exists()) {
                    return true;
                }
                outputStream = new FileOutputStream(path);
                image = ImageIO.read(new FileInputStream(path.replace(ext, extOri)));
                if (image == null) {
                    return true;
                }
                imageOutputStream = ImageIO.createImageOutputStream(outputStream);
                imageWriter = (ImageWriter) ImageIO.getImageWritersBySuffix("jpeg").next();
                IIOMetadata metadata = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image), null);
                JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
                jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
                jpegParams.setCompressionQuality((float) quantity);
                imageWriter.setOutput(imageOutputStream);
                imageWriter.write(metadata, new IIOImage(image, null, metadata), null);
                return true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e2) {
                        return false;
                    }
                }

                if (imageOutputStream != null) {
                    try {
                        imageOutputStream.close();
                    } catch (IOException e2) {
                        return false;
                    }
                }

                if (imageWriter != null) {
                    imageWriter.dispose();
                }

                if (image != null) {
                    image.flush();
                }
            }
        } else {
            return true;
        }
    }
}
